#ifndef DEXEL_HPP
#define DEXEL_HPP

#include <vector>
#include <list>
#include "point.hpp"

//using std::vector;
//using std::list;

using namespace std;


enum body_state //the state of the concrete space point
  {
    UNDEF,
    SOLID,
    AIR,
    SURFACE
  };

struct interval // 1d space solid interval
{
  interval()
  {b=e=0;
    
  }
  
  interval(double _b, double _e)
  {
    b=_b;
    e=_e;
  }
  
  body_state state(double v) const
  {
    if(v>=b && v<=e && b!=e) return SOLID;
    else return AIR;
  }
  
  double b;
  double e;
};


  
class dexel //single dexel - "space column"
{
public:
  dexel(){};
  virtual ~dexel(){}
  
  virtual int solids() const {return 0;}
  virtual double solid_begin(int i)const {return NA;}
  virtual double solid_end(int i)const {return NA;}
  virtual bool check()const {return false;}
  virtual double min()const{return NA;}
  virtual double max()const{return NA;}

  virtual double border(double z0, double z1) const
  {
    return NA;
  }
  

  virtual body_state state(double)const{return AIR;} 
  
  
  virtual void substract(double begin, double end){};
  virtual void substract(const interval&){};
  virtual void substract(const dexel &){};

  void get_values(vector<double> *vals) const
  {
    throw; //pure dexels never in use
  }
  
  void get_intervals(list<interval> *ints) const
  {
    throw; //pure dexels never in use
  }
  

};

class uni_dexel // : public dexel
{
public:
  uni_dexel(){};
  uni_dexel(double,double);

  const uni_dexel& operator= (const dexel&);
    
  int solids() const;
  double solid_begin(int i) const;
  double solid_end(int i) const;
  bool check() const;
  double min() const;
  double max() const;
  
  double border(double z0, double z1) const;
  
  body_state state(double)const;
  
  
  void substract(double begin, double end);
  void substract(const interval &i);

  void substract(const dexel&);

  void get_values(vector<double> *vals) const;
  void get_intervals(vector<interval> *ints) const;
  
private:
  vector<double> v;

};

  
class inter_dexel // : public dexel
{
public:
  inter_dexel(){};
  inter_dexel(double,double);

  const inter_dexel& operator= (const dexel&);
    
  int solids() const;
  double solid_begin(int i) const;
  double solid_end(int i) const;
  bool check()const{return true;} 
  double min() const;
  double max() const;
  

  body_state state(double) const;

  double border(double z0, double z1) const;
  
  
  void substract(double begin, double end);
  void substract(const interval &i);
  
  void substract(const dexel&){};

  void get_values(vector<double> *vals) const;
  void get_intervals(list<interval> *ints) const;
  
  

private:
  list<interval> ints;
  typedef list<interval>::const_iterator c_iter;
  typedef list<interval>::iterator iter;
  
};


#endif
